package luminus.origin.commands.rewrite

import luminus.origin.utils.send
import org.bukkit.GameMode
import org.bukkit.entity.Player
import taboolib.common.LifeCycle
import taboolib.common.platform.Awake
import taboolib.common.platform.ProxyCommandSender
import taboolib.common.platform.command.*
import taboolib.common.platform.function.submit
import taboolib.module.lang.asLangText
import taboolib.module.lang.asLangTextList
import taboolib.module.lang.sendLang

@CommandHeader("gamemode", aliases = ["gm"], permission = "luminus.gamemode", permissionDefault = PermissionDefault.OP)
object Gamemode {



    @CommandBody
    val main = mainCommand {
        execute<ProxyCommandSender> { sender, _, _ ->
            sender.asLangTextList("commands-gamemode-help").forEach {
                sender.send(it)
            }
        }
        literal("spectator", "3", "spec") {
            execute<ProxyCommandSender> { sender, _, _ ->
                setGameMode(sender, GameMode.SPECTATOR)
            }
            dynamic(optional = true) {
                suggestPlayers()
                execute<ProxyCommandSender> { sender, _, argument ->
                    setGameMode(sender, GameMode.SPECTATOR, argument)
                }
            }
        }
        literal("creative", "1", "c") {
            execute<ProxyCommandSender> { sender, _, _ ->
                setGameMode(sender, GameMode.CREATIVE)
            }
            dynamic(optional = true) {
                suggestPlayers()
                execute<ProxyCommandSender> { sender, _, argument ->
                    setGameMode(sender, GameMode.CREATIVE, argument)
                }
            }
        }
        literal("survival", "0", "s") {
            execute<ProxyCommandSender> { sender, _, _ ->
                setGameMode(sender, GameMode.SURVIVAL)
            }
            dynamic(optional = true) {
                suggestPlayers()
                execute<ProxyCommandSender> { sender, _, argument ->
                    setGameMode(sender, GameMode.SURVIVAL, argument)
                }
            }
        }
        literal("adventure", "2", "a") {
            execute<ProxyCommandSender> { sender, _, _ ->
                setGameMode(sender, GameMode.ADVENTURE)
            }
            dynamic(optional = true) {
                suggestPlayers()
                execute<ProxyCommandSender> { sender, _, argument ->
                    setGameMode(sender, GameMode.ADVENTURE, argument)
                }
            }
        }
    }

    private fun setGameMode(sender: ProxyCommandSender, gameMode: GameMode, playerName: String? = null) {
        val target = if (playerName != null) {
            val player = sender.castSafely<Player>()?.server?.getPlayer(playerName)
                ?: return sender.sendLang("commands-gamemode-error", playerName)
            player
        } else {
            sender.castSafely<Player>() ?: return sender.sendLang("commands-gamemode-console-cannot-use")
        }

        target.gameMode = gameMode
        val modeName = when (gameMode) {
            GameMode.SURVIVAL -> sender.asLangText("commands-gamemode-survival")
            GameMode.CREATIVE -> sender.asLangText("commands-gamemode-creative")
            GameMode.ADVENTURE -> sender.asLangText("commands-gamemode-adventure")
            GameMode.SPECTATOR -> sender.asLangText("commands-gamemode-spectator")
        }


        if (playerName != null) {
            sender.sendLang("commands-gamemode-gamemode-changed-other", target.name, modeName)
            sender.sendLang("commands-gamemode-gamemode-changed-by", modeName, sender.name)
        } else {
            sender.sendLang("commands-gamemode-gamemode-changed-self", modeName)
        }
    }

    @Awake(LifeCycle.ENABLE)
    fun init() {
        simpleCommand("spectator", listOf("gmsp"), permission = "luminus.gamemode") { sender, _ ->
            submit(async = true) { setGameMode(sender, GameMode.SPECTATOR) }
        }
        simpleCommand("creative", listOf("gmc"), permission = "luminus.gamemode") { sender, _ ->
            submit(async = true) { setGameMode(sender, GameMode.CREATIVE) }
        }
        simpleCommand("survival", listOf("gms"), permission = "luminus.gamemode") { sender, _ ->
            submit(async = true) { setGameMode(sender, GameMode.SURVIVAL) }
        }
        simpleCommand("adventure", listOf("gma"), permission = "luminus.gamemode") { sender, _ ->
            submit(async = true) { setGameMode(sender, GameMode.ADVENTURE) }
        }
    }

}